"""
!/usr/bin/env python
-*- coding: utf-8 -*-
@Author  : MarkJia
@Site    : 
@File    : 22、pytest插件.py
"""

import pytest

"""
pytest 插件分类
pytest hook 介绍
pytest hook 执行顺序

"""

# 插件：
# 1、外部插件（第三方库）： pip install 插件
# 2、本地插件：如放在 conftest 的 fixtrue 函数
# 3、内置插件：hook函数

"""
# 常用的插件： 重点是 1 和 2 和 4 和  5（多重断言）
# 1、控制用例执行顺序： pip install pytest-ordering
# 2、分布式执行用例： pip install xdist
# 3、控制用例的依赖关系： pip install pytest-dependecy
# 4、失败用例重跑： pip install pytest-rerunfailures
# 5、多重校验：pip install pytest-assume
# 6、用例随机执行：pip install pytest-random-order
# 7、测试报告： pip install pytest-html

"""


#  =================  pytest --collect-only 收集用例 ==========================    pytest  22、pytest插件.py --collect-only
# 按顺序执行
def test_case1():
    print('第一条用例')


def test_case2():
    print('第二条用例')


# ===================  1、控制用例执行顺序： pip install pytest-ordering ========================

# 改变顺序  先执行 order = 1 的用例
# 加上装饰器
@pytest.mark.run(order=2)
def test_case3():
    print('第三条用例')


@pytest.mark.run(order=1)
def test_case4():
    print('第四条用例')


# =======================  2、分布式并发执行用例： pip install xdist   是多进程 ： 使用场景,运行用例时加  pytest -n cpu核（数字)/auto
# 正常运行以下 3 个用例，总耗时 6s
import time
from Autowebui_frame.common.Logger import *


# 使用分布式多进程运行：pytest -n auto  22、pytest插件.py   总耗时 4s 左右。执行用例越多，效果越明显
def test_sleep1():
    time.sleep(1)
    logger.info('等待1s')
    print('等待1s')


def test_sleep2():
    time.sleep(2)
    logger.info('等待2s')
    print('等待2s')


def test_sleep3():
    time.sleep(3)
    logger.info('等待3s')
    print('等待3s')


# =================  3、失败用例重跑  安装插件： pip install pytest-rerunfailures =============  一般跑用例遇到网络原因、环境原因导致的用例失败
# 参数说明 ： reruns 表示失败后执行几次   reruns_delay 表示失败后等待几秒，再重新执行
# =============   可以放在单个用例，也可以放在类中 ==============
# 命令行执行 ： pytest -vs --reruns=3 --reruns-delay=2

import pytest
import random


@pytest.mark.flaky(reruns=3, reruns_delay=2)
def test_rerun():
    a = random.randint(1, 3)
    assert a == 2


# =============================  4、pytest多重校验。安装 ： pip install pytest-assume  =================================
# 前面的断言失败不影响后面的断言执行
from pytest_assume.plugin import assume


def add(a, b):
    return a + b


def test_assume():
    with assume:
        assert add(1, 2) == 4
        assert 1 == 1


# =======================   5、内置插件：Hook函数（镜子函数） =========================
"""
Hook函数
    是个函数，在系统触发时被系统调用
    自动触发机制
    Hook 函数的名称是确定的
    pytest 有非常多的勾子函数
    使用时直接编写函数体

执行过程：
    1、收集用例
    2、执行setup
    3、调用测试用例
    4、执行teardown
    5、获取测试结果
"""
from typing import Optional


# 放在 conftest文件中
def pytest_runtest_setup(item: "Item") -> None:
    print("hook: setup")


def pytest_runtest_teardown(item: "Item", nextitem: Optional["Item"]) -> None:
    print('hook: teardown')
